package com.morty.product.service.impl;

import com.morty.config.annotation.Rlock;
import com.morty.config.utils.RedisLock;
import com.morty.product.entity.Product;
import com.morty.product.mapper.product.ProductMapper;
import com.morty.product.service.ProductService;
import com.morty.user.controller.UserControllerApi;
import com.morty.user.vo.UserInfoVo;
import com.morty.user.vo.UserLockVo;
import io.seata.spring.annotation.GlobalTransactional;
import io.seata.tm.api.transaction.Propagation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Slf4j
@Service
public class ProductServiceImpl implements ProductService {

	@Resource
	ProductMapper productMapper;

	@Autowired
	UserControllerApi userControllerApi;

	@Autowired
	RedisLock redisLock;

	public Product getProductById(String proId){
		Product product = productMapper.selectByPrimaryKey(proId);
		log.info("product{}: {}",proId,product);
		return product;
	}

	/**
	 * 新增
	 * @param product
	 * @return
	 */
	@GlobalTransactional(propagation= Propagation.REQUIRES_NEW,name="insertProduct",rollbackFor = {Exception.class})
	public int insertProduct(Product product) throws Exception {
		productMapper.updateById(newUpProduct());
		userControllerApi.insertUser(newUser());
		int result = productMapper.insert(product);
		if(result>-1) {
			throw new Exception("111111111111");
		}
		return result;
	}

	private UserInfoVo newUser(){
		UserInfoVo user = new UserInfoVo();
		user.setUserId("11");
		user.setAge(16);
		user.setUserName("haohao");
		user.setJob("boss");
		return user;
	}

	private UserInfoVo newUpUser(){
		UserInfoVo user = new UserInfoVo();
		user.setUserId("1");
		user.setAge(16);
		user.setUserName("haohao");
		user.setJob("boss");
		return user;
	}

	private UserLockVo newUpUserLock(){
		UserLockVo user = new UserLockVo();
		user.setUserId("1");
		user.setAge(16);
		user.setUserName("haohao");
		user.setJob("boss");
		return user;
	}

	private Product newProduct(){
		Product productTemp = new Product();
		productTemp.setProId("111");
		productTemp.setProCode("111");
		productTemp.setProName("安娜");
		productTemp.setProStatus(1);
		return productTemp;
	}

	private Product newUpProduct(){
		Product productTemp = new Product();
		productTemp.setProId("2");
		productTemp.setProCode("002");
		productTemp.setProName("狄安娜");
		productTemp.setProStatus(1);
		return productTemp;
	}

	@GlobalTransactional(rollbackFor = {Exception.class})
	public String testSeata(){
		boolean isFail = true;
		userControllerApi.updateUser(newUpUser());
		productMapper.insert(newProduct());
		try {
			Thread.sleep(10*1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		if (isFail) {
			int divide = 0;
			int resul = 100 / divide;
		}
		productMapper.updateById(newUpProduct());
		return "SUCCESS";
	}

	@GlobalTransactional(rollbackFor = {Exception.class})
	public String testSeataLock(){
		boolean isFail = true;
		userControllerApi.updateUserLock(newUpUserLock());
		productMapper.insert(newProduct());
		try {
			Thread.sleep(10*1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		if (isFail) {
			int divide = 0;
			int resul = 100 / divide;
		}
		productMapper.updateById(newUpProduct());
		return "SUCCESS";
	}

	/**
	 * 修改/作废
	 * @param product
	 * @return
	 */
	public int updateProduct(Product product){
		return productMapper.updateById(product);
	}

	@Rlock(localKey="testRedis",waitTime=20,leaseTime=20)
	public String testRedis(){
		try {
			Thread.sleep(10*1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return "SUCCESS";
	}

	public String testRedisUtil(String lock){
		redisLock.tryLock("testRedisUtil:", lock);
		try {
			Thread.sleep(10*1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		redisLock.unLock("testRedisUtil:", lock);
		return "SUCCESS";
	}
}
